package rhplus.gestor;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.LinkedList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import rhplus.persistencia.ContaDeUtilizador;
import rhplus.persistencia.Hospital;
import rhplus.sistema.CodigoPostal;
import rhplus.sistema.UtensiliosParaStrings;
import rhplus.utilizador.Colaborador;
import rhplus.utilizador.Pessoa;

@SuppressWarnings("serial")
public class GestorDeSistema extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    public static final String VISUALIZAR_CONTAS_DE_UTILIZADOR = "visualizar_contas_de_utilizador";
    public static final String ACTIVAR_CONTAS_DE_UTILIZADOR = "activar_contas_de_utilizador";
    public static final String DESACTIVAR_CONTAS_DE_UTILIZADOR = "desactivar_contas_de_utilizador";
    public static final String INSERIR_HOSPITAL = "inserir_hospital";
    public static final String ALTERAR_HOSPITAL = "alterar_hospital";
    public static final String REMOVER_HOSPITAL = "remover_hospital";
    public static final String VISUALIZAR_HOSPITAL = "visualizar_hospital";
    public static final String VISUALIZAR_HOSPITAIS = "visualizar_hospitais";
    public static final String LOGIN = "login";
    public static final String LOGOUT = "logout";
    public static final String PESQUISAR_HOSPITAL = "pesquisar_hospital";

    /*
     * (non-Java-doc)
     *
     * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
     *      HttpServletResponse response)
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String accao = (String) request.getParameter("accao");

        if (accao.equals(GestorDeSistema.LOGIN)) {
            login(request, response, session);
        } else if (accao.equals(GestorDeSistema.LOGOUT)) {
            logout(request, response, session);
        } else if (accao.equals(GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR)) {
            visualizarContasDeUtilizador(request, response, session);
        } else if (accao.equals(GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR)) {
            activarContasDeUtilizador(request, response, session);
        } else if (accao.equals(GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR)) {
            desactivarContasDeUtilizador(request, response, session);
        } else if (accao.equals(GestorDeSistema.INSERIR_HOSPITAL)) {
            inserirHospital(request, response, session);
        } else if (accao.equals(GestorDeSistema.ALTERAR_HOSPITAL)) {
            alterarHospital(request, response, session);
        } /* else if (accao.equals(GestorDeSistema.REMOVER_HOSPITAL))
        removerHospital(request, response, session);
        else if (accao.equals(GestorDeSistema.VISUALIZAR_HOSPITAL))
        visualizarHospital(request, response, session);
        else if (accao.equals(GestorDeSistema.VISUALIZAR_HOSPITAIS))
        visualizarHospitais(request, response, session);*/ else if (accao.equals(GestorDeSistema.PESQUISAR_HOSPITAL)) {
            pesquisarHospital(request, response, session);
        } else {
            IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
            session.setAttribute("excepcao", illegal_argument_exception.toString());
            response.sendRedirect("/mostra_erro.jsp");
        }
    }

    /*
     * (non-Java-doc)
     *
     * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
     *      HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    // efectua o login
    public void login(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        try {
            if (dadosEstaoValidos(request, GestorDeSistema.LOGIN)) {

                Hashtable<String, Object> dados_do_login = populaTabelaLogin(request);
                String username = (String) dados_do_login.get("var_username");

                if (ContaDeUtilizador.existeUsername(username)) {

                    String password = (String) dados_do_login.get("var_password");

                    // Username é valido e existe && Password é valida.
                    // Verificar se é a Password de acesso à conta
                    // correspondente ao Username.
                    if (ContaDeUtilizador.eValida(username, password)) {

                        // Set maximum inactive interval permited by the server
                        session.setMaxInactiveInterval(500);
                        session = request.getSession();

                        session.setAttribute("username", username);

                        session.setAttribute("label_bem_vindo", username);

                        session.setAttribute("session_id", session.getId());
                        String perfil = ContaDeUtilizador.devolvePerfil(username);
                        session.setAttribute("perfil", perfil);

                        Pessoa utilizador = Colaborador.devolve(username);
                        session.setAttribute("utilizador", utilizador);

                        if (perfil.equals("cliente_empresa") || perfil.equals("particular")) {
                            response.sendRedirect("/area_cliente.jsp");
                        } else {
                            response.sendRedirect("/area_colaborador.jsp");
                        }

                    } else {
                        Hashtable<String, String> erros = new Hashtable<String, String>();
                        erros.put("login", "O login falhou por algum motivo. Aparentemente o username ou password foi introduzido incorrectamente.");

                        session.setAttribute("campos_invalidos", erros);

                        response.sendRedirect("/login.jsp");
                    }
                } else {
                    Hashtable<String, String> erros = new Hashtable<String, String>();
                    erros.put("username", "Username não existe.");

                    session.setAttribute("campos_invalidos", erros);

                    response.sendRedirect("/login.jsp");
                }
            } else {
                Hashtable<String, String> erros = devolveTabelaDeErrosParaLogin(request);
                if (erros.isEmpty()) {
                    session.setAttribute("campos_invalidos", null);
                } else {
                    session.setAttribute("campos_invalidos", erros);
                }

                response.sendRedirect("/login.jsp");
            }

        } catch (ClassNotFoundException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (InstantiationException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (IllegalAccessException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        }
    }

    private void pesquisarHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        try {
            Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

            String numero_de_hospital = request.getParameter("numero_de_hospital");
            if (numero_de_hospital == null || numero_de_hospital.trim().equals("")) {
                tabela_de_erros.put("numero_de_hospital", "Campo Obrigat�rio. Não pode estar vazio.");
            } else if (!UtensiliosParaStrings.eUmNumero(numero_de_hospital)) {
                tabela_de_erros.put("numero_de_hospital", "O campo N�mero de Hospital dever� ser num�rico.");
            } else if (numero_de_hospital.length() >= 10) {
                tabela_de_erros.put("numero_de_hospital", "O campo N�mero de Hospital deve ter menos que 10 algarismos.");
            }

            if (!tabela_de_erros.isEmpty()) {
                session.setAttribute("erros", tabela_de_erros);
                response.sendRedirect("pesquisarHospital.jsp");
            } else {
                session.removeAttribute("erros");

                if (Hospital.existeHospital(Long.parseLong(numero_de_hospital))) {
                    response.sendRedirect("Gestor?gestor=gestor_de_sistema&accao=alterar_hospital&sub_accao=primeira&id_hospital=" + numero_de_hospital);
                } else {
                    tabela_de_erros.put("numero_de_hospital", "N�o existe nenhum hospital com o id introduzido.");
                    session.setAttribute("erros", tabela_de_erros);
                    response.sendRedirect("pesquisarHospital.jsp");
                }
            }
        } catch (IOException e) {
            //  } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.PESQUISAR_HOSPITAL);
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            //  } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.PESQUISAR_HOSPITAL);
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            // } catch (InstantiationException e) {
            e.printStackTrace();
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.PESQUISAR_HOSPITAL);
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            // } catch (IllegalAccessException e) {
            e.printStackTrace();
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.PESQUISAR_HOSPITAL);
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            //  } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.PESQUISAR_HOSPITAL);
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        }
    }

    public void logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        session.invalidate();

        response.sendRedirect("/index.jsp");

    }

    private Hashtable<String, Object> populaTabelaLogin(final HttpServletRequest request) {
        Hashtable<String, Object> dados = new Hashtable<String, Object>();

        // recebe dados da webpage com request
        dados.put("var_username", (String) request.getParameter("username"));
        dados.put("var_password", (String) request.getParameter("password"));

        return dados;
    }

    /**
     * Conta de Utilizador
     *
     * @param request
     * @param response
     * @param session
     */
    public void visualizarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        try {
            session.setAttribute("contas_de_utilizador_a_visualizar", ContaDeUtilizador.devolveTodas());

        } catch (SQLException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
        } catch (InstantiationException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
        }
    }

    @SuppressWarnings("unchecked")
    public void activarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        try {
            LinkedList<ContaDeUtilizador> lista_de_contas_de_utilizador = (LinkedList<ContaDeUtilizador>) session.getAttribute("contas_de_utilizador_a_activar");

            for (int i = 0; i < lista_de_contas_de_utilizador.size(); i++) {
                String username = lista_de_contas_de_utilizador.get(i).getUsername();
                ContaDeUtilizador.desactiva(username);
            }

        } catch (SQLException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (InstantiationException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
        }
    }

    @SuppressWarnings("unchecked")
    public void desactivarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        try {
            LinkedList<ContaDeUtilizador> lista_de_contas_de_utilizador = (LinkedList<ContaDeUtilizador>) session.getAttribute("contas_de_utilizador_a_desactivar");

            for (int i = 0; i < lista_de_contas_de_utilizador.size(); i++) {
                String username = lista_de_contas_de_utilizador.get(i).getUsername();
                ContaDeUtilizador.activa(username);
            }

        } catch (SQLException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (InstantiationException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
            System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
        }
    }

    public void inserirHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        try {
            if (dadosEstaoValidos(request, GestorDeSistema.INSERIR_HOSPITAL)) {
                Hospital dados_do_hospital = populaTabelaInserirHospital(request);

                Hospital.insere(dados_do_hospital);
                session.removeAttribute("erros");

                session.setAttribute("msg_sucesso", "Hospital inserido com sucesso.");
                session.setAttribute("nome_pagina_link", "inser��o Hospital");
                session.setAttribute("pagina_link", "/inserirHospital.jsp");
                response.sendRedirect("/mostra_sucesso.jsp");
                

            } else {
                session.setAttribute("erros", devolveTabelaDeErrosParaInserirHospital(request));

                // Propaga dados, previamente inseridos, pela sessao
                session.setAttribute("nome", request.getParameter("nome"));
                session.setAttribute("numero_na_rede", request.getParameter("numero_na_rede"));
                session.setAttribute("cidade", request.getParameter("cidade"));
                session.setAttribute("morada", request.getParameter("morada"));
                session.setAttribute("telefone", request.getParameter("telefone"));
                session.setAttribute("director", request.getParameter("director"));
                session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
                session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
                session.setAttribute("localidade", request.getParameter("localidade"));

                response.sendRedirect("/inserirHospital.jsp");
            }
        } catch (NumberFormatException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (InstantiationException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (IllegalAccessException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (IOException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        }
    }

    public void alterarHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        try {
            String sub_accao = request.getParameter("sub_accao");
            if (sub_accao != null && sub_accao.equals("primeira")) {

                Long id_hospital = Long.parseLong(request.getParameter("id_hospital"));
                Hospital hospital = Hospital.devolve(id_hospital);

                // Propaga dados, previamente inseridos, pela sessao
                session.setAttribute("nome", hospital.getNome());
                session.setAttribute("numero_na_rede", hospital.getNumeroNaRede());
                session.setAttribute("cidade", hospital.getCidade());
                session.setAttribute("morada", hospital.getMorada());
                CodigoPostal codig = CodigoPostal.devolve(hospital.getCodigoPostal());
                session.setAttribute("prefixo_codigo_postal", codig.getPrefixo());
                session.setAttribute("sufixo_codigo_postal", codig.getSufixo());
                session.setAttribute("telefone", hospital.getTelefone());
                session.setAttribute("director", hospital.getDirector());
                session.setAttribute("id_hospital", id_hospital);
                session.setAttribute("localidade", codig.getLocalidade());

                session.setAttribute("existem_dados", new Boolean(true));

                response.sendRedirect("/alterarHospital.jsp");

            } else if (sub_accao != null && sub_accao.equals("segunda")) {
                if (dadosEstaoValidos(request, GestorDeSistema.ALTERAR_HOSPITAL)) {
                    
                    Hospital dados_do_hospital = populaTabelaInserirHospital(request);
                    dados_do_hospital.setId(Long.parseLong(request.getParameter("id")));
                    Hospital.altera(dados_do_hospital);
                    session.removeAttribute("erros");
                    session.setAttribute("msg_sucesso", "Hospital alterado com sucesso.");
                    session.setAttribute("nome_pagina_link", "de pesquisar hospital");
                    session.setAttribute("pagina_link", "Gestor?gestor=gestor_de_sistema&accao=pesquisar_hospital");
                    response.sendRedirect("/mostra_sucesso.jsp");

                } else {
                    session.setAttribute("erros", devolveTabelaDeErrosParaInserirHospital(request));

                    // Propaga dados, previamente inseridos, pela sessao
                    session.setAttribute("nome", request.getParameter("nome"));
                    session.setAttribute("numero_na_rede", request.getParameter("numero_na_rede"));
                    session.setAttribute("cidade", request.getParameter("cidade"));
                    session.setAttribute("morada", request.getParameter("morada"));
                    session.setAttribute("telefone", request.getParameter("telefone"));
                    session.setAttribute("director", request.getParameter("director"));
                    session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
                    session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
                    session.setAttribute("localidade", request.getParameter("localidade"));

                    response.sendRedirect("/alterarHospital.jsp");

                }
            } else {
                session.setAttribute("excepcao", "Url incorrecto.");
                response.sendRedirect("/mostra_erro.jsp");
            }
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (InstantiationException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        } catch (IllegalAccessException e) {

            e.printStackTrace();
            session.setAttribute("excepcao", e.toString());
            response.sendRedirect("/mostra_erro.jsp");
        }
    }
    /*  public void removerHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    try {
    int id_hospital = Integer.getInteger((String) request.getParameter("id_hospital"));
    Hospital.remove(id_hospital);

    } catch (SQLException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
    } catch (InstantiationException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
    }
    }

    public void visualizarHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    try {
    System.out.println((String) request.getParameter("id_hospital"));
    int id_hospital = Integer.parseInt((String) request.getParameter("id_hospital"));
    Hospital hospital = Hospital.devolve(id_hospital);
    session.setAttribute("hospital", hospital);





    } catch (SQLException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
    } catch (InstantiationException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
    }
    }

    public void visualizarHospitais(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    try {
    session.setAttribute("hospitais_a_visualizar", Hospital.devolveTodos());

    } catch (SQLException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
    } catch (InstantiationException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    session.setAttribute("excepcao", e.toString());
    response.sendRedirect("/mostra_erro.jsp");
    System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
    }
    }*/

    private Hospital populaTabelaInserirHospital(final HttpServletRequest request) {

        String nome = request.getParameter("nome");
        int numero_na_rede = Integer.parseInt(request.getParameter("numero_na_rede"));
        String cidade = request.getParameter("cidade");
        String morada = request.getParameter("morada");
        int telefone = Integer.parseInt(request.getParameter("telefone"));
        String director = request.getParameter("director");

        int prefixo_codigo_postal = populaTabelaCodigoPostal(request).getPrefixo();
        int sufixo_codigo_postal = populaTabelaCodigoPostal(request).getSufixo();
        if (!CodigoPostal.existe(prefixo_codigo_postal, sufixo_codigo_postal)) {
            CodigoPostal.insere(populaTabelaCodigoPostal(request));
        }
        // ja existe o codigo postal, por isso é necessário ir buscar o id_codigo postal
        Long codigo = CodigoPostal.devolve(prefixo_codigo_postal, sufixo_codigo_postal).getIdCodigoPostal();

        return new Hospital(nome, numero_na_rede, cidade, morada, telefone, director, codigo);
    }

    private CodigoPostal populaTabelaCodigoPostal(final HttpServletRequest request) {

        return new CodigoPostal(Integer.parseInt(request.getParameter("prefixo_codigo_postal")),
                Integer.parseInt(request.getParameter("sufixo_codigo_postal")),
                request.getParameter("localidade"));
    }

    private CodigoPostal requestCodigoPostal(final HttpServletRequest request) {
        return new CodigoPostal(Integer.parseInt(request.getParameter("prefixo_codigo_postal")), Integer.parseInt(request.getParameter("sufixo_codigo_postal")), request.getParameter("localidade"));
    }

    private boolean dadosEstaoValidos(final HttpServletRequest request, final String action) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        return devolveTabelaDeErros(request, action).isEmpty();
    }

    private Hashtable<String, String> devolveTabelaDeErros(final HttpServletRequest request, final String action) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        if (action.equals(GestorDeSistema.LOGIN)) {
            return devolveTabelaDeErrosParaLogin(request);
        } else if (action.equals(GestorDeSistema.INSERIR_HOSPITAL)) {
            return devolveTabelaDeErrosParaInserirHospital(request);
        } else if (action.equals(GestorDeSistema.ALTERAR_HOSPITAL)) {
            return devolveTabelaDeErrosParaAlterarHospital(request);
        } else {
            return new Hashtable<String, String>();
        }
    }

    private Hashtable<String, String> devolveTabelaDeErrosParaLogin(final HttpServletRequest request) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

        String username = (String) request.getParameter("username");
        if (username == null || username.trim().equals("")) {
            tabela_de_erros.put("username", "Campo Obrigatório. Não pode estar vazio.");
        } else if (username.length() < 6) {
            tabela_de_erros.put("username", "Tamanho inválido. O campo username deverá ter pelo menos 6 caracteres.");
        } else if (!UtensiliosParaStrings.eLoginValido((String) request.getParameter("username"))) {
            tabela_de_erros.put("username", "O campo Username n�o pode conter caracteres especiais.");
        }


        String password = (String) request.getParameter("password");
        if (password == null || password.trim().equals("")) {
            tabela_de_erros.put("password", "Campo Obrigatório. Não pode estar vazio.");
        }
        if (password != null && !password.trim().equals("") && password.length() < 6) {
            tabela_de_erros.put("password", "Tamanho inválido. O campo password deverá ter pelo menos 6 caracteres.");
        }

        return tabela_de_erros;
    }

    private Hashtable<String, String> devolveTabelaDeErrosParaInserirHospital(final HttpServletRequest request) {
        Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

        String nome = (String) request.getParameter("nome");
        if (nome == null || nome.trim().equals("")) {
            tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");
        }

        String numero_na_rede = (String) request.getParameter("numero_na_rede");
        if (numero_na_rede == null || numero_na_rede.trim().equals("")) {
            tabela_de_erros.put("numero_na_rede", "Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(numero_na_rede)) {
            tabela_de_erros.put("numero_na_rede", "O campo Número na rede deverá ser numérico.");
        } else if (Integer.parseInt(numero_na_rede) <= 0 || Integer.parseInt(numero_na_rede) >= 100000000) {
            tabela_de_erros.put("numero_na_rede", "Número na rede inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");
        }

        String cidade = (String) request.getParameter("cidade");
        if (cidade == null || cidade.trim().equals("")) {
            tabela_de_erros.put("cidade", "Campo Obrigatório. Não pode estar vazio.");
        }

        String morada = (String) request.getParameter("morada");
        if (morada == null || morada.trim().equals("")) {
            tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");
        }

        String telefone = (String) request.getParameter("telefone");
        if (telefone == null || telefone.trim().equals("")) {
            tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(telefone)) {
            tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");
        }

        String director = (String) request.getParameter("director");
        if (director == null || director.trim().equals("")) {
            tabela_de_erros.put("director", "Campo Obrigatório. Não pode estar vazio.");
        }

        // Codigo Postal
        String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
        if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals("")) {
            tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal)) {
            tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");
        }

        String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
        if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals("")) {
            tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal)) {
            tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");
        }

      
        String localidade = (String) request.getParameter("localidade");
        if (localidade == null || localidade.trim().equals("")) {
            tabela_de_erros.put("localidade", "Campo Obrigat�rio. N�o pode estar vazio.");
        } else if (UtensiliosParaStrings.eApenasLetras(localidade)) {
            tabela_de_erros.put("localidade", "O campo localidade pode apenas conter caracteres alfab�ticos.");
        }


        return tabela_de_erros;
    }

    private Hashtable<String, String> devolveTabelaDeErrosParaAlterarHospital(final HttpServletRequest request) {
        Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

        String nome = (String) request.getParameter("nome");
        if (nome == null || nome.trim().equals("")) {
            tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");
        }

        String numero_na_rede = (String) request.getParameter("numero_na_rede");
        if (numero_na_rede == null || numero_na_rede.trim().equals("")) {
            tabela_de_erros.put("numero_na_rede", "Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(numero_na_rede)) {
            tabela_de_erros.put("numero_na_rede", "O campo Número na rede deverá ser numérico.");
        } else if (Integer.parseInt(numero_na_rede) <= 0 || Integer.parseInt(numero_na_rede) >= 100000000) {
            tabela_de_erros.put("numero_na_rede", "Número na rede inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");
        }

        String cidade = (String) request.getParameter("cidade");
        if (cidade == null || cidade.trim().equals("")) {
            tabela_de_erros.put("cidade", "Campo Obrigatório. Não pode estar vazio.");
        }

        String morada = (String) request.getParameter("morada");
        if (morada == null || morada.trim().equals("")) {
            tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");
        }

        String telefone = (String) request.getParameter("telefone");
        if (telefone == null || telefone.trim().equals("")) {
            tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(telefone)) {
            tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");
        }

        String director = (String) request.getParameter("director");
        if (director == null || director.trim().equals("")) {
            tabela_de_erros.put("director", "Campo Obrigatório. Não pode estar vazio.");
        }

        // Codigo Postal
        String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
        if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals("")) {
            tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal)) {
            tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");
        }

        String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
        if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals("")) {
            tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
        } else if (!UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal)) {
            tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");
        }

        return tabela_de_erros;
    }
}
